# -*- coding: utf-8 -*-
# @File    : yiban.py
# @Author  : Xiewh
# @Email   : 1679860867@qq.com
# @Time    : 2020/11/29 1:15
# @Function:

import os
import json
import time
import math
import random
import base64
import requests
import threading
import pyexcel_xlsx as pe
import pyexcel_io.writers
import common.captcha as ct
import common.headers as head
from common.api_url import *
from common.api_constant import *
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcsl_v1_5
from main import USER_LIST_PATH, YIBAN_VERSION
from datetime import datetime, timedelta

# 账号列表
USER_LIST = []
# 投票列表
VOTE_TITLE_LIST = []
# 主账号信息
MAIN_USER = {}
# 投票发起人
ACTOR_ID = 0
# 群名
GROUP_NAME = ""
# 群列表
GROUP_LIST = []
# 群ID
GROUP_ID = ""
# 群主ID
PUID = ""
# 自动识别错误次数
CAPTCHA_COUNT = 5
# 投票过期时间
VOTE_TIME_OUT = str((datetime.now() + timedelta(days=3)).strftime("%Y-%m-%d %H:%M"))
# 增量按 0.07 算
VOTE_ADD_NUM = 0.07
# 增量按 0.07 算
VOTE_ISSUE_NUM = 0
# 投票总数量
VOTE_NUM = 0
# 投票发布时间间隔
VOTE_TIME_FLUSH = 0.5
# 配置项
CONFIG = {}
# 免验证码投票上限
MAX_VOTE_NUM = 5
# 线程数
VOTE_THREAD = 2

def get_user_list():
    global USER_LIST
    global VOTE_TITLE_LIST
    global CONFIG
    global VOTE_THREAD
    global VOTE_TIME_FLUSH
    try:
        data = pe.get_data(USER_LIST_PATH)
        if data.get('user', 0) == 0 or data.get('title', 0) == 0:
            return {'code': -1, 'msg': '读取Excel数据失败'}
        del data['user'][0]
        del data['title'][0]
        del data['config'][0]
        # 整理账号
        for n in data['user']:
            try:
                user = str(n[0])
                pasw = str(n[1])
                # 登录获取 access_token
                ret = yiban_login(user, pasw)
                if ret['code'] != 1:
                    print('错误：', ret['msg'])
                    continue
                # 获取COOKIE
                cookie = get_yiban_cookie(user, ret['data'].get('access_token'))
                if cookie['code'] != 1:
                    print('错误：', cookie['msg'])
                    continue
                temp = {
                    'name': ret['data'].get('user').get('name'),
                    'user': user,
                    'pasw': pasw,
                    'user_id': ret['data'].get('user').get('user_id'),
                    'token': ret['data'].get('access_token'),
                    'cookie': cookie['data']
                }
                USER_LIST.append(temp)
            except Exception as ex:
                print("错误：", n, ex)
        # 整理投票列表
        for n in data['title']:
            temp = {
                'title': str(n[0]),
                'subjectTxt': str(n[1]),
                'subjectTxt_1': str(n[2]),
                'subjectTxt_2': str(n[3]),
                'subjectTxt_3': str(n[4]),
            }
            VOTE_TITLE_LIST.append(temp)
        # 读取CONFIG
        for n in data['config']:
            CONFIG[n[0]] = n[1]
        if CONFIG.get('VOTE_THREAD', 0) != 0:
            VOTE_THREAD = CONFIG.get('VOTE_THREAD')
        if CONFIG.get('VOTE_TIME_FLUSH', 0) != 0:
            VOTE_TIME_FLUSH = CONFIG.get('VOTE_TIME_FLUSH')
        if USER_LIST.__len__() <= 0:
            return {'code': -1, 'msg': '可用账号不足'}
        if VOTE_TITLE_LIST.__len__() <= 0:
            return {'code': -1, 'msg': '投票列表为空'}
        return {'code': 1, 'msg': '获取成功', 'data': USER_LIST}
    except Exception as ex:
        return {'code': -1, 'msg': '读取Excel数据失败' + str(ex)}


# 易班登录
def yiban_login(user, pasw):
    try:
        # 登录mobile端易班
        login_url = url_split(YIBAN_MOBILE_HOST, YIBAN_PASSPORT_LOGIN, 2) + '?'
        login_param = {
            'account': user,
            'passwd': yiban_login_pasw_encrypt(pasw),
            'ct': 2,
            'app': 1,
            'v': YIBAN_VERSION,
            'token': '',
            'device': 'SAMSUNG SM-G973N',
            'identify': '35156412084611',
            'sversion': 25
        }
        ret = json.loads(requests.get(login_url, params=login_param, headers=head.Mobile).text)
        if int(ret['response']) != 100:
            return {'code': -1, 'msg': '账号 ' + user + ret['message']}
        return {'code': 1, 'msg': '账号 ' + user + ' ' + ret['message'], 'data': ret['data']}
    except Exception as ex:
        return {'code': -1, 'msg': '账号 ' + user + str(ex)}


# 易班WEB端cookie获取
def get_yiban_cookie(user, token):
    try:
        cookie_url = url_split(YIBAN_CHROME_HOST, YIBAN_TOKEN_LOGIN, 2) + '?' + 'access_token=' + token
        ret = requests.post(cookie_url, headers=head.Chrome)
        cookie = ret.cookies.get_dict()
        if cookie.__len__() <= 0:
            return {'code': -1, 'msg': '账号 ' + user + ' 获取COOKIE失败'}
        temp = ''
        for n in cookie:
            temp = temp + n + '=' + cookie[n] + ';'
        return {'code': 1, 'msg': '获取成功', 'data': temp}
    except Exception as ex:
        return {'code': -1, 'msg': '账号 ' + user + ' ' + str(ex)}


# 易班群信息获取
def get_yiban_group_list():
    global GROUP_LIST
    try:
        headers = head.Chrome
        headers['cookie'] = USER_LIST[0]['cookie']
        group_url = url_split(YIBAN_CHROME_HOST, YIBAN_GROUP_LIST, 2)
        ret = json.loads(requests.get(group_url, headers=headers).text)
        if int(ret['code']) != 200:
            return {'code': -1, 'msg': ret['message']}
        GROUP_LIST = []
        for i in ret['data']:
            if int(i['type']) != 1:
                continue
            temp = {
                'group_id': i['id'],
                'puid': i['puid'],
                'name': i['name'],
            }
            GROUP_LIST.append(temp)
        if GROUP_LIST.__len__() == 0:
            return {'code': -1, 'msg': '该账号群列表为空'}
        return {'code': 1, 'msg': '获取成功', 'data': GROUP_LIST}
    except Exception as ex:
        return {'code': -1, 'msg': '获取群列表失败 ' + str(ex)}


# 易班群信息获取
def get_yiban_group_list_2():
    global GROUP_LIST
    try:
        headers = head.Mobile
        token = USER_LIST[0]['token']
        group_url = url_split(YIBAN_MOBILE_HOST, YIBAN_GROUP_LIST_2, 2) + '?my_group_type=0&num=80&access_token=' + token
        ret = json.loads(requests.get(group_url, headers=headers).text)
        if int(ret['response']) != 100:
            return {'code': -1, 'msg': ret['message']}
        GROUP_LIST = []
        for i in ret['data']['myCreateGroups']['list']:
            if int(i['type']) != 1:
                continue
            temp = {
                'group_id': i['group_id'],
                'puid': i['user_id'],
                'name': i['name']
            }
            GROUP_LIST.append(temp)
        for i in ret['data']['myJoinGroups']['list']:
            if int(i['type']) != 1:
                continue
            temp = {
                'group_id': i['group_id'],
                'puid': i['user_id'],
                'name': i['name']
            }
            GROUP_LIST.append(temp)
        if GROUP_LIST.__len__() == 0:
            return {'code': -1, 'msg': '该账号群列表为空'}
        return {'code': 1, 'msg': '获取成功', 'data': GROUP_LIST}
    except Exception as ex:
        return {'code': -1, 'msg': '获取群列表失败 ' + str(ex)}


# 获取EGPA
def get_yiban_group_info():
    try:
        headers = head.Mobile
        group_egpa_url = url_split(YIBAN_MOBILE_HOST, YIBAN_GROUP_EGPA, 2) + GROUP_ID + '?' + 'access_token=' + MAIN_USER[
            'token']
        ret = json.loads(requests.get(group_egpa_url, headers=headers).text)
        if int(ret['response']) != 100:
            return {'code': -1, 'msg': ret['message']}
        group_egpa = ret['data']['group']['egpa']
        not_user = []

        # for k, v in enumerate(USER_LIST):
        #     isEq = 0
        #     for i in ret['data']['members']:
        #         if i['user_id'] == v['user_id']:
        #             isEq = 1
        #             break
        #     if isEq == 0:
        #         temp = {
        #             'name': v['name'],
        #             'user': v['user']
        #         }
        #         del USER_LIST[k]
        #         not_user.append(temp)
        return {'code': 1, 'msg': '获取成功', 'not_user': not_user, 'egpa': group_egpa}
    except Exception as ex:
        return {'code': -1, 'msg': '获取群EGPA失败 ' + str(ex)}


# 设置任务的主账号
def set_yiban_main_user():
    global MAIN_USER
    try:
        MAIN_USER = USER_LIST[0]
        return {'code': 1, 'msg': '设置成功', 'user': MAIN_USER['user']}
    except Exception as ex:
        return {'code': -1, 'msg': '设置主账号失败 ' + str(ex)}


# 设置易班群
def set_yiban_group(group):
    global GROUP_ID
    global PUID
    global GROUP_NAME
    try:
        GROUP_ID = GROUP_LIST[group]['group_id']
        PUID = GROUP_LIST[group]['puid']
        GROUP_NAME = GROUP_LIST[group]['name']
        return {'code': 1, 'msg': '设置成功', 'puid': PUID, 'group_id': GROUP_ID, 'name': GROUP_NAME}
    except Exception as ex:
        return {'code': -1, 'msg': '设置群信息失败 ' + str(ex)}


# 查询授权信息
def get_group_sq():
    try:
        group_sq_url = url_split(SERVICE_HOST, SERVICE_GROUP_SQ_API) + "?group_id=" + GROUP_ID
        ret = json.loads(requests.get(group_sq_url).text)
        if ret['code'] != 1:
            return {'code': -1, 'msg': ret['msg']}
        else:
            return {'code': 1, 'msg': ret['msg']}
    except Exception as ex:
        return {'code': -1, 'msg': '授权群查询失败' + str(ex)}


# 设置验证码
def set_captcha():
    global CAPTCHA_COUNT
    try:
        if CONFIG.get('CAPTCHA_COUNT', 0) != 0:
            CAPTCHA_COUNT = int(CONFIG.get('CAPTCHA_COUNT'))
        i = 0
        save_file = MAIN_USER['user'] + '.png'
        while True:
            i += 1
            # 处理验证码
            if i > CAPTCHA_COUNT:
                ret = ct.get_captcha(MAIN_USER['cookie'], 1)
                if ret['code'] != 1:
                    print('错误：', ret['msg'])
                    time.sleep(1)
                    continue
                print('错误：自动识别错误次数已达上限，请手动输入')
                yzm = input("请输入弹出的验证码：")
            else:
                ret = ct.get_captcha(MAIN_USER['cookie'])
                if ret['code'] != 1:
                    print('错误：', ret['msg'])
                    time.sleep(1)
                    continue
                base64_image = ret['data']
                ret = ct.image_transfer(base64_image, save_file)
                if ret['code'] != 1:
                    print('错误：', ret['msg'])
                    time.sleep(1)
                    continue
                capt = ct.appdemo_generalocr(file_path=save_file)
                if capt['code'] != 1:
                    print('错误：' + capt['msg'])
                    time.sleep(1)
                    continue
                yzm = capt['data']
            ret = yiban_vote_add(yzm)
            if ret['code'] != 1:
                print('错误：' + ret['msg'], yzm)
                time.sleep(1)
                continue
            if os.path.exists(save_file):
                os.remove(save_file)
            return {'code': 1, 'msg': '验证码 ' + yzm, 'capt': yzm}
    except Exception as ex:
        return {'code': -1, 'msg': '获取验证码失败 ' + str(ex)}


# 发布20条投票 必免影响验证码识别
def release_beta_vote():
    try:
        while True:
            ret = yiban_vote_add()
            if ret['code'] != 200:
                time.sleep(1)
                break
        return {'code': 1, 'msg': '发布成功 '}
    except Exception as ex:
        return {'code': -1, 'msg': '发布无需验证码的投票失败 ' + str(ex)}


# 发布投票
def release_vote(capt=None):
    global VOTE_ISSUE_NUM
    global VOTE_TIME_FLUSH
    try:
        if CONFIG.get('VOTE_TIME_FLUSH', 0) != 0:
            VOTE_TIME_FLUSH = CONFIG.get('VOTE_TIME_FLUSH')
        errorlist = []
        for VOTE_ISSUE_NUM in range(1, VOTE_NUM + 1):
            ret = yiban_vote_add(capt)
            if ret['code'] != 200:
                errorlist.append({
                    'code': -1,
                    'msg': '错误：第' + str(VOTE_ISSUE_NUM) + '条投票' + ret['msg']
                })
            time.sleep(VOTE_TIME_FLUSH)
        return {'code': 1, 'msg': '发布成功 ', 'data': errorlist}
    except Exception as ex:
        return {'code': -1, 'msg': '发布投票失败 ' + str(ex)}


# 发布投票
def release_20vote(num=5):
    global VOTE_ISSUE_NUM
    global VOTE_TIME_FLUSH
    try:
        errorlist = []
        user_number = USER_LIST.__len__()
        for n in range(0, num):
            time_start = time.time()
            for v in range(0, user_number):
                headers = head.Chrome
                headers['cookie'] = USER_LIST[v]['cookie']
                ret = yiban_20vote_add(headers)
                if ret['code'] != 200:
                    errorlist.append({
                        'code': -1,
                        'msg': '错误：第' + str(VOTE_ISSUE_NUM) + '条投票' + ret['msg']
                    })
                VOTE_ISSUE_NUM = VOTE_ISSUE_NUM + 1
                time.sleep(0.25)
            time_end = time.time()
            run_time = round((time_end - time_start), 2)
            sleeptime = 60 + 5
            if run_time < sleeptime and n != num - 1:
                time.sleep(sleeptime - run_time)
        return {'code': 1, 'msg': '发布成功 ', 'data': errorlist}
    except Exception as ex:
        return {'code': -1, 'msg': '发布投票失败 ' + str(ex)}


# 易班投票发起
def yiban_vote_add(capt=None):
    try:
        headers = head.Chrome
        headers['cookie'] = MAIN_USER['cookie']
        vote = VOTE_TITLE_LIST[random.randint(0, VOTE_TITLE_LIST.__len__() - 1)]
        vote_add_url = url_split(YIBAN_CHROME_HOST, YIBAN_VOTE_ADD, 2)
        param = {
            "puid": PUID,
            "group_id": GROUP_ID,
            "title": vote['title'],
            "subjectTxt": vote['subjectTxt'],
            "subjectPic": "", "options_num": "3", "scopeMin": "1", "scopeMax": "1", "minimum": "1",
            "voteValue": VOTE_TIME_OUT,
            "voteKey": "2", "public_type": "0", "isAnonymous": "2", "voteIsCaptcha": "0", "istop": "1",
            "sysnotice": "2", "isshare": "1", "rsa": "1", "dom": ".js-submit",
            "subjectTxt_1": vote['subjectTxt_1'],
            "subjectTxt_2": vote['subjectTxt_2'],
            "subjectTxt_3": vote['subjectTxt_3'],
            "captcha": capt
        }
        ret = json.loads(requests.post(vote_add_url, data=param, headers=headers).text)
        if ret['code'] != 200:
            return {'code': -1, 'msg': ret['message']}
        return {'code': 1, 'msg': ret['message']}
    except Exception as ex:
        return {'code': -1, 'msg': '投票发起失败 ' + str(ex)}


# 易班投票发起
def yiban_20vote_add(headers):
    try:
        vote = VOTE_TITLE_LIST[random.randint(0, VOTE_TITLE_LIST.__len__() - 1)]
        vote_add_url = url_split(YIBAN_CHROME_HOST, YIBAN_VOTE_ADD, 2)
        param = {
            "puid": PUID,
            "group_id": GROUP_ID,
            "title": vote['title'],
            "subjectTxt": vote['subjectTxt'],
            "subjectPic": "", "options_num": "3", "scopeMin": "1", "scopeMax": "1", "minimum": "1",
            "voteValue": VOTE_TIME_OUT,
            "voteKey": "2", "public_type": "0", "isAnonymous": "2", "voteIsCaptcha": "0", "istop": "1",
            "sysnotice": "2", "isshare": "1", "rsa": "1", "dom": ".js-submit",
            "subjectTxt_1": vote['subjectTxt_1'],
            "subjectTxt_2": vote['subjectTxt_2'],
            "subjectTxt_3": vote['subjectTxt_3']
        }
        ret = json.loads(requests.post(vote_add_url, data=param, headers=headers).text)
        if ret['code'] != 200:
            return {'code': -1, 'msg': ret['message']}
        return {'code': 1, 'msg': ret['message']}
    except Exception as ex:
        return {'code': -1, 'msg': '投票发起失败 ' + str(ex)}


# 易班获取投票列表
def yiban_vote_list(page=1, size=10):
    try:
        headers = head.Chrome
        headers['cookie'] = MAIN_USER['cookie']
        list_url = url_split(YIBAN_CHROME_HOST, YIBAN_VOTE_LIST, 2)
        param = {
            'group_id': GROUP_ID,
            'puid': PUID,
            'page': page,
            'size': size,
            'status': 1,
            'sort': 1,
            'time': 0
        }
        ret = json.loads(requests.post(list_url, data=param, headers=headers).text)
        if ret['code'] != 200:
            return {'code': -1, 'msg': ret['message']}
        return {'code': 1, 'msg': ret['message'], 'data': ret['data']['list']}
    except Exception as ex:
        return {'code': -1, 'msg': '获取投票列表失败 ' + str(ex)}


# 易班投票 投票
def yiban_vote_act(headers, actor_id, vote_id, voptions_id):
    try:
        act_url = url_split(YIBAN_CHROME_HOST, YIBAN_VOTE_ACT, 2)
        param = {
            'group_id': GROUP_ID,
            'puid': PUID,
            'vote_id': vote_id,
            'actor_id': actor_id,
            'voptions_id': voptions_id,
            'minimum': 1,
            'scopeMax': 1
        }
        ret = json.loads(requests.post(act_url, data=param, headers=headers).text)
        if ret['code'] != 200:
            return {'code': -1, 'msg': ret['message']}
        return {'code': 1, 'msg': ret['message']}
    except Exception as ex:
        return {'code': -1, 'msg': '投票失败 ' + str(ex)}


# 易班投票 点赞
def yiban_vote_love(headers, actor_id, vote_id):
    try:
        love_url = url_split(YIBAN_CHROME_HOST, YIBAN_VOTE_EDITLOVE, 2)
        param = {
            'group_id': GROUP_ID,
            'puid': PUID,
            'vote_id': vote_id,
            'actor_id': actor_id,
            'flag': 1
        }
        ret = json.loads(requests.post(love_url, data=param, headers=headers).text)
        if ret['code'] != 200:
            return {'code': -1, 'msg': ret['message']}
        return {'code': 1, 'msg': ret['message']}
    except Exception as ex:
        return {'code': -1, 'msg': '点赞失败 ' + str(ex)}


# 易班投票 评论
def yiban_vote_comment(headers, actor_id, author_id, vote_id, mount_id):
    try:
        comment_url = url_split(YIBAN_CHROME_HOST, YIBAN_VOTE_ADDCOMMENT, 2)
        param = {
            'group_id': GROUP_ID,
            'puid': PUID,
            'vote_id': vote_id,
            'actor_id': actor_id,
            'author_id': author_id,
            'mountid': mount_id,
            'msg': "1",
            'reply_comment_id': 0,
            'reply_user_id': 0
        }
        ret = json.loads(requests.post(comment_url, data=param, headers=headers).text)
        if ret['code'] != 200:
            return {'code': -1, 'msg': ret['message']}
        return {'code': 1, 'msg': ret['message']}
    except Exception as ex:
        return {'code': -1, 'msg': '评论失败 ' + str(ex)}


# 等待
def yiban_vote_need():
    timeflush = 0.15
    i = 0
    while True:
        list = ["\\", "|", "/", "-"]
        i += 1
        print("\r状态：正在发布投票 {}".format(list[i % 4]) + "\t{0:6d}".format(VOTE_ISSUE_NUM) + "|" + str(VOTE_NUM),
              end="", flush=True)
        if VOTE_ISSUE_NUM == VOTE_NUM:
            break
        time.sleep(timeflush)


# 多线程投票
def yiban_vote_thread(vote_list, bc):
    try:
        headers = head.Chrome.copy()
        headers['cookie'] = USER_LIST[bc]['cookie']
        actor_id = USER_LIST[bc]['user_id']
        for val in vote_list:
            vote_id = val['id']
            author_id = val['User_id']  # 发起人的ID
            mount_id = val['Mount_id']
            voptions_id = val['option_list'][random.randint(0, int(val['optionsNum']) - 1)]['id']
            # 点赞
            ret = yiban_vote_love(headers=headers, actor_id=actor_id, vote_id=vote_id)
            print('状态：ID', actor_id, vote_id, '点赞', ret['msg'])
            # 投票
            ret = yiban_vote_act(headers=headers, actor_id=actor_id, vote_id=vote_id, voptions_id=voptions_id)
            print('状态：ID', actor_id, vote_id, '投票', ret['msg'])
            # 评论
            ret = yiban_vote_comment(headers=headers, actor_id=actor_id, author_id=author_id, vote_id=vote_id,
                                     mount_id=mount_id)
            print('状态：ID', actor_id, vote_id, '评论', ret['msg'])
    except Exception as ex:
        return {'code': -1, 'msg': '评论失败 ' + str(ex)}

# 易班 普通模式 稳定
def yiban_stable_mode(egpa_num):
    # 增量
    global VOTE_NUM
    global VOTE_THREAD
    global VOTE_ADD_NUM
    global MAX_VOTE_NUM
    try:
        user_num = USER_LIST.__len__()
        if VOTE_THREAD > user_num:
            VOTE_THREAD = user_num
        print('状态：正在获取验证码')
        ret = set_captcha()
        if ret['code'] != 1:
            return print('错误：', ret['msg'])
        print('成功：' + ret['msg'])
        print('状态：准备发布投票...')
        time.sleep(1)
        os.system('cls')

        # 循环发布
        VOTE_NUM = math.ceil(egpa_num / VOTE_ADD_NUM / user_num)
        vote_need = threading.Thread(target=yiban_vote_need)
        release = threading.Thread(target=release_vote, args=(ret['capt'],))
        vote_need.start()
        release.start()
        vote_need.join()
        release.join()
        print('\n成功：发布投票成功，准备开始点赞...')
        time.sleep(1)

        # 发布完成开始点赞
        size = 100
        page = math.ceil(VOTE_NUM / size) + 1

        for x in range(1, page):
            print('状态：正在获取投票列表...')
            while True:
                ret = yiban_vote_list(page=x, size=size)
                if ret['code'] != 1:
                    print('错误：' + ret['msg'])
                    time.sleep(1)
                    continue
                else:
                    break
            print('状态：正在评论点赞投票...')
            vote_list = ret['data']
            count = math.ceil(user_num / VOTE_THREAD)
            print(USER_LIST)
            bc = 0
            for e in range(0, count):
                t = {}
                for a in range(0, VOTE_THREAD):
                    if bc == user_num:
                        break
                    t[a] = str(a)
                    t[a] = threading.Thread(target=yiban_vote_thread, args=(vote_list, bc,))
                    t[a].start()
                    bc = bc + 1
                for k in range(0, t.__len__()):
                    t[k].join()
                del t
        return {'code': 1, 'msg': '操作成功 '}
    except Exception as ex:
        return {'code': -1, 'msg': '投票发起失败 ' + str(ex)}


def yiban_20vote_model():
    global VOTE_NUM
    global VOTE_THREAD
    global VOTE_ADD_NUM
    global MAX_VOTE_NUM
    try:
        user_num = USER_LIST.__len__()
        if VOTE_THREAD > user_num:
            VOTE_THREAD = user_num

        os.system('cls')
        # 循环发布
        VOTE_NUM = user_num * MAX_VOTE_NUM
        if VOTE_NUM > 1000:
            return {'code': -1, 'msg': str(VOTE_NUM) + ' * ' + str(MAX_VOTE_NUM) + ' 超过1000'}
        print('提示：预计涨值', str(round((VOTE_NUM * 0.07 * user_num), 2)))
        vote_need = threading.Thread(target=yiban_vote_need)
        release = threading.Thread(target=release_20vote, args=(MAX_VOTE_NUM,))
        vote_need.start()
        release.start()
        vote_need.join()
        release.join()

        # 开始点赞
        print('\n成功：发布投票成功，准备开始点赞...')
        time.sleep(1)

        # 发布完成开始点赞
        size = VOTE_NUM
        page = 1
        print('状态：正在获取投票列表...')
        while True:
            ret = yiban_vote_list(page=page, size=size)
            if ret['code'] != 1:
                print('错误：' + ret['msg'])
                time.sleep(1)
                continue
            else:
                break
        print('状态：正在评论点赞投票...')
        vote_list = ret['data']
        bc = 0
        count = math.ceil(user_num / VOTE_THREAD)
        for e in range(0, count):
            t = {}
            for a in range(0, VOTE_THREAD):
                if bc == user_num:
                    break
                t[a] = str(a)
                t[a] = threading.Thread(target=yiban_vote_thread, args=(vote_list, bc,))
                t[a].start()
                bc = bc + 1
            for k in range(0, t.__len__()):
                t[k].join()
            del t
        return {'code': 1, 'msg': '操作成功 '}
    except Exception as ex:
        return {'code': -1, 'msg': '任务执行失败 ' + str(ex)}


def yiban_love_model(stop):
    global VOTE_NUM
    global VOTE_THREAD
    global VOTE_ADD_NUM
    global MAX_VOTE_NUM
    try:
        os.system('cls')
        # 开始点赞
        user_num = USER_LIST.__len__()
        if VOTE_THREAD > user_num:
            VOTE_THREAD = user_num
        print('准备开始点赞...')
        time.sleep(1)
        # 发布完成开始点赞
        size = stop
        page = 1
        print('状态：正在获取投票列表...')
        while True:
            ret = yiban_vote_list(page=page, size=size)
            if ret['code'] != 1:
                print('错误：' + ret['msg'])
                time.sleep(1)
                continue
            else:
                break
        print('状态：正在评论点赞投票...')
        vote_list = ret['data']
        bc = 0
        count = math.ceil(user_num / VOTE_THREAD)
        for e in range(0, count):
            t = {}
            for a in range(0, VOTE_THREAD):
                if bc == user_num:
                    break
                t[a] = str(a)
                t[a] = threading.Thread(target=yiban_vote_thread, args=(vote_list, bc,))
                t[a].start()
                bc = bc + 1
            for k in range(0, t.__len__()):
                t[k].join()
            del t
        return {'code': 1, 'msg': '操作成功 '}
    except Exception as ex:
        return {'code': -1, 'msg': '任务执行失败 ' + str(ex)}



# 易班登录密码加密
def yiban_login_pasw_encrypt(pasw):
    # 易班登录密码 RSA加密公钥
    public_key = "-----BEGIN PUBLIC KEY-----\n\
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxbzZk3gEsbSe7A95iCIk\
59Kvhs1fHKE6zRUfOUyTaKd6Rzgh9TB/jAK2ZN7rHzZExMM9kw6lVwmlV0VabSmO\
YL9OOHDCiEjOlsfinlZpMZ4VHg8gkFoOeO4GvaBs7+YjG51Am6DKuJWMG9l1pAge\
96Uhx8xWuDQweIkjWFADcGLpDJJtjTcrh4fy8toE0/0zJMmg8S4RM/ub0q59+VhM\
zBYAfPmCr6YnEZf0QervDcjItr5pTNlkLK9E09HdKI4ynHy7D9lgLTeVmrITdq++\
mCbgsF/z5Rgzpa/tCgIQTFD+EPPB4oXlaOg6yFceu0XUQEaU0DvAlJ7Zn+VwPkkq\
JEoGudklNePHcK+eLRLHcjd9MPgU6NP31dEi/QSCA7lbcU91F3gyoBpSsp5m7bf5\
//OBadjWJDvl2KML7NMQZUr7YXqUQW9AvoNFrH4edn8d5jY5WAxWsCPQlOqNdybM\
vKF2jhjIE1fTWOzK+AvvFyNhxer5bWGU4S5LTr7QNXnvbngXCdkQfrcSn/ydQXP0\
vXfjf3NhpluFXqWe5qUFKXvjY6+PdrE/lvTmX4DdvUIu9NDa2JU9mhwAPPR1yjjp\
4IhgYOTQL69ZQcvy0Ssa6S25Xi3xx2XXbdx8svYcQfHDBF1daK9vca+YRX/DzXxl\
1S4uGt+FUWSwuFdZ122ZCZ0CAwEAAQ==\n\
-----END PUBLIC KEY-----"
    pu_key = RSA.importKey(public_key)
    cipher = Cipher_pkcsl_v1_5.new(pu_key)
    cipher_text = base64.b64encode(cipher.encrypt(pasw.encode('utf8')))
    return cipher_text
